package com.cci.kangdao.service.impl;

import com.alibaba.fastjson.JSON;
import com.cci.kangdao.common.RedisKeys;
import com.cci.kangdao.dao.ServiceStationDao;
import com.cci.kangdao.dao.TechDealWithWorkOrderDao;
import com.cci.kangdao.dao.WorkOrderFlowTDao;
import com.cci.kangdao.dao.WorkOrderTDao;
import com.cci.kangdao.dao.WorkOrderTrackTDao;
import com.cci.kangdao.dao.model.UserT;
import com.cci.kangdao.dao.model.WorkOrderT;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.TrackService;
import com.cci.kangdao.utilTool.CollectionUtils;
import com.cci.kangdao.utilTool.Date_Util;
import com.cci.kangdao.utilTool.Dictionaries;
import com.cci.kangdao.utilTool.HttpClient;
import com.cci.kangdao.utilTool.JsonUtils;
import com.cci.kangdao.utilTool.LocalTimeUtil;
import com.cci.kangdao.utilTool.NumberUtils;
import com.cci.kangdao.utilTool.ParameterTool;
import com.cci.kangdao.utilTool.PropertiesUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author William Du
 * @date 2019/11/7
 */
@Service
public class TrackServiceImpl implements TrackService {

    private Logger log = Logger.getLogger(this.getClass().getName());

    //存放企业信息（猎鹰中创建的服务）
    private static Map<String, Object> golden_company = new HashMap<String, Object>();
    //map 存放企业与服务站的关系，在猎鹰里相当于   service 与 terminal的关系
    // key:companyId_serviceId  value:sid_tid
    private static Map<String, Object> company_service = new HashMap<String, Object>();
    //map 存放服务站与轨迹的关系，在猎鹰里相当于 terminal 与 trace 的关系
    // key:serviceId_orderId_orderNo value:tid_trid
    private static Map<String, Object> trace_service = new HashMap<String, Object>();
    //自定义轨迹点参数IMEI
    private static String PROP_IMEI = "IMEI";
    //自定义轨迹点参数TIMESTAMP
    private static String PROP_TIMESTAMP = "timestamp";

    @Resource
    private TechDealWithWorkOrderDao techDealWithWorkOrderDao;
    @Resource
    private RedisClientUtils redisClientUtils;
    @Resource
    private WorkOrderTrackTDao workOrderTrackTDao;
    @Resource
    private WorkOrderTDao workOrderTDao;
    @Resource
    private ServiceStationDao serviceStationDao;
    @Resource
    private WorkOrderFlowTDao workOrderFlowTDao;

    @Override
    @Transactional
    public String createTrace(Map<String, Object> orderMap) {
        //获取必要参数
        //企业Id
        String companyId = MapUtils.getString(orderMap, "CompanyId","");
        //企业编号
        String companyNo = MapUtils.getString(orderMap, "CompanyNo","");
        //服务站Id
        String serviceStationId = MapUtils.getString(orderMap, "ServiceStationId","");
        //服务站名称
        String serviceStationName = MapUtils.getString(orderMap, "StationName","");
        //工单Id
        String orderId = MapUtils.getString(orderMap, "OrderId","");
        //工单编号
        String orderNo = MapUtils.getString(orderMap, "OrderNo","");
        //高德key
        String goldenKey = PropertiesUtil.getProperties("projectconfig.properties", "Golden.GoldenKey");
        if (StringUtils.isEmpty(companyId) || StringUtils.isEmpty(serviceStationId) || StringUtils.isEmpty(orderId) || StringUtils.isEmpty(orderNo) || StringUtils.isEmpty(goldenKey)) {
            return "missParam";
        }
        //判断内存中是否存在当前企业
        if(!golden_company.containsKey(companyId)) {
            //从数据库查询该企业是否存在
            Map<String,Object> cmap = techDealWithWorkOrderDao.getGolden_Company(orderMap);
            if(MapUtils.isNotEmpty(cmap)) {
                //数据库存在该企业，将信息放入内存中
                golden_company.put(companyId, MapUtils.getString(cmap, "gsid"));
            }else {
                //不存在该企业，则在高德中创建该企业信息
                Map<String,Object> createServiceMap = new HashMap<String,Object>();
                createServiceMap.put("key", goldenKey);
                createServiceMap.put("name", companyId);
                createServiceMap.put("desc", companyNo);
                try {
                    String createServiceResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "createService"), createServiceMap);
                    JSONObject jsb = JSONObject.fromObject(createServiceResult);
                    String errorCode = jsb.getString("errcode");
                    if("10000".equals(errorCode)) {
                        //成功(获取 sid)
                        JSONObject data = (JSONObject) jsb.get("data");
                        String sid = data.getString("sid");
                        golden_company.put(companyId, sid);
                        // 增加服务自定义参数
                        prepareCustomProps(goldenKey,sid);
                    }else {
                        //创建失败
                        log.error(errorCode);
                        return "fail";
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(),e);
                    return "fail";
                }
            }

        }
        orderMap.put("sid", golden_company.get(companyId));
        //判断内存中是否存在该企业与服务站的关系
        String csKey = companyId+"_"+serviceStationId;
        if(!company_service.containsKey(csKey)) {
            //内存中不存在该关系，从数据库查询是否存在
            Map<String,Object> csMap = techDealWithWorkOrderDao.getGolden_Company_Service(orderMap);
            if(MapUtils.isNotEmpty(csMap)) {
                String sid = MapUtils.getString(csMap, "gsid");
                String tid = MapUtils.getString(csMap, "gtid");
                if(StringUtils.isNotEmpty(sid) && StringUtils.isNotEmpty(tid)) {
                    //数据库存在该企业与服务站关系，将关系放入全局变量中
                    company_service.put(csKey, sid+"_"+tid);
                }else {
                    //数据库存在该企业与服务站关系，但必要参数缺失，需要重新保存该关系
                    //在高德创建该关系
                    sid = golden_company.get(companyId).toString();
                    Map<String,Object> createTerminalMap = new HashMap<String,Object>();
                    createTerminalMap.put("key", goldenKey);
                    createTerminalMap.put("sid", sid);
                    createTerminalMap.put("name", serviceStationName);
                    try {
                        String createTerminalResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "createTerminal"), createTerminalMap);
                        JSONObject jsb = JSONObject.fromObject(createTerminalResult);
                        String errorCode = jsb.getString("errcode");
                        if("10000".equals(errorCode)) {
                            //成功(获取 tid)
                            JSONObject data = (JSONObject) jsb.get("data");
                            tid = data.getString("tid");
                            orderMap.put("tid", tid);
                            //将获取到的tid存入数据库
                            techDealWithWorkOrderDao.saveCompany_Service(orderMap);
                            //将关系存入缓存
                            company_service.put(csKey, sid+"_"+tid);
                        }else {
                            //创建失败
                            log.info(errorCode);
                            return "fail";
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                        return "fail";
                    }
                }
            }else {
                //数据库不存在该企业与服务站关系，需要重新保存该关系
                //在高德创建该关系
                String sid = golden_company.get(companyId).toString();
                Map<String,Object> createTerminalMap = new HashMap<String,Object>();
                createTerminalMap.put("key", goldenKey);
                createTerminalMap.put("sid", golden_company.get(companyId));
                createTerminalMap.put("name", serviceStationId);
                //createTerminalMap.put("desc", serviceStationName);
                try {
                    String createTerminalResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "createTerminal"), createTerminalMap);
                    JSONObject jsb = new JSONObject();
                    jsb = JSONObject.fromObject(createTerminalResult);
                    String errorCode = jsb.getString("errcode");
                    if("10000".equals(errorCode)) {
                        //成功(获取 tid)
                        JSONObject data = (JSONObject) jsb.get("data");
                        String tid = data.getString("tid");
                        orderMap.put("tid", tid);
                        //将获取到的tid存入数据库
                        int saveCS = techDealWithWorkOrderDao.saveCompany_Service(orderMap);
                        //将关系存入缓存
                        company_service.put(csKey, sid+"_"+tid);
                    }else if("20009".equals(errorCode)){
                        String getTerminalResult = HttpClient.doGet(PropertiesUtil.getProperties("goldenUrl.properties", "getTerminal"), createTerminalMap);
                        JSONObject getJson = JSONObject.fromObject(getTerminalResult);
                        if("10000".equals(getJson.getString("errcode"))){
                            JSONObject data = (JSONObject) getJson.get("data");
                            JSONArray service = data.getJSONArray("results");
                            String tid = service.getJSONObject(0).getString("tid");
                            orderMap.put("tid",tid);
                            techDealWithWorkOrderDao.saveCompany_Service(orderMap);
                            company_service.put(csKey, sid+"_"+tid);
                        }else{
                            log.info(errorCode);
                            return "fail";
                        }
                    }else {
                        //创建失败
                        log.info(errorCode);
                        return "fail";
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(),e);
                    return "fail";
                }
            }
        }
        String sid_tid =  MapUtils.getString(company_service, csKey);
        String[] arrsid_tid = sid_tid.split("_");
        if(arrsid_tid.length!=2) {
            return "fail";
        }
        //判断轨迹（看内存中是否存在轨迹）
        String tsKey = serviceStationId+"_"+orderId+"_"+orderNo;
        if(!trace_service.containsKey(tsKey)) {
            //查看数据库是否存在该关系
            Map<String,Object> tsMap = new HashMap<String,Object>();
            tsMap = techDealWithWorkOrderDao.getTrace_Service(orderMap);
            if(null==tsMap || tsMap.size()==0) {
                //数据库不存在此关系，在高德中创建轨迹
                Map<String,Object> createTraceMap = new HashMap<String,Object>();
                createTraceMap.put("key", goldenKey);
                createTraceMap.put("sid", arrsid_tid[0]);
                createTraceMap.put("tid", arrsid_tid[1]);
                try {
                    String createTraceResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "createTrace"), createTraceMap);
                    JSONObject jsb = JSONObject.fromObject(createTraceResult);
                    String errorCode = jsb.getString("errcode");
                    if("10000".equals(errorCode)) {
                        //成功(获取 tid)
                        JSONObject data = (JSONObject) jsb.get("data");
                        String trid = data.getString("trid");
                        orderMap.put("trid", trid);
                        //将获取到的tid存入数据库
                        int saveTS = techDealWithWorkOrderDao.saveTrace_Service(orderMap);
                        //将关系存入缓存
                        trace_service.put(tsKey, arrsid_tid[1]+"_"+trid);
                    }else {
                        //创建失败
                        log.info(errorCode);
                        return "fail";
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    log.error(e.getMessage(),e);
                    return "fail";
                }
            }else {
                //数据库存在此关系，将关系维护到内存中
                String tid = MapUtils.getString(orderMap, "tid");
                String trid = MapUtils.getString(tsMap, "gtrid");
                trace_service.put(tsKey, tid+"_"+trid);
            }
        }
        return "success";
    }
    private void prepareCustomProps(String key,String sid){
        try {
            Map<String,Object> getPropsMap = new HashMap<>(2);
            getPropsMap.put("key",key);
            getPropsMap.put("sid",sid);
            String getPropsResult = HttpClient.doGet(PropertiesUtil.getProperties("goldenUrl.properties", "getProps"),getPropsMap);
            JSONObject getPropsResultObject = JSONObject.fromObject(getPropsResult);
            String errorCode = null != getPropsResultObject ? getPropsResultObject.getString("errcode") : "";
            if("10000".equals(errorCode)) {
                List<String> propString = new ArrayList<>(2);
                JSONObject dataObj = getPropsResultObject.getJSONObject("data");
                if(null != dataObj && dataObj.containsKey("results")){
                    JSONArray propArray = dataObj.getJSONArray("results");
                    propArray.forEach(result ->{
                        JSONObject propObj = (JSONObject) result;
                        propString.add(propObj.getString("column"));
                    });
                }
                if(!propString.contains(PROP_IMEI)){
                    addProp(key,sid,PROP_IMEI,"string");
                }
                if(!propString.contains(PROP_TIMESTAMP)){
                    addProp(key,sid,PROP_TIMESTAMP,"string");
                }
            }else{
                log.error("获取自定义参数异常，错误码"+errorCode+"错误信息"+getPropsResultObject.getString("errmsg"));
            }
        } catch (Exception e) {
            log.error("增加自定义参数异常"+e.getMessage(),e);
        }
    }
    private void addProp(String key,String sid,String column,String type){
        Map<String,Object> addPropsMap = new HashMap<>();
        addPropsMap.put("key",key);
        addPropsMap.put("sid",sid);
        addPropsMap.put("column",column);
        addPropsMap.put("type",type);
        String addPropsResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "addProps"), addPropsMap);
        JSONObject addPropsResultObject = JSONObject.fromObject(addPropsResult);
        String errorCode = addPropsResultObject.getString("errcode");
        if(!"10000".equals(errorCode)) {
            log.error("高德轨迹增加自定义参数失败，错误码"+errorCode+"错误信息"+addPropsResultObject.getString("errmsg"));
        }
    }

    @Override
    public void uploadTrace(WorkOrderT workOrderT, List<Map<String, Object>> locationMapList,String IMEI) {
        Map<String,Object> propertiesMap = getGDProperties(workOrderT);
        // 准备自定义参数
        String goldenKey = MapUtils.getString(propertiesMap,"goldenKey");
        String serviceId = MapUtils.getString(propertiesMap,"serviceId");
        prepareCustomProps(goldenKey,serviceId);
        // 上传轨迹点
        Integer retryCount = 0;
        retryCount = upload(propertiesMap,locationMapList,retryCount,IMEI);
        if(retryCount >= 100){
            log.error("高德经纬度上传失败，重试次数超限,未上传数据信息："+ JsonUtils.toJsonString(locationMapList));
        }
    }
    private Integer upload(Map<String,Object> propertiesMap,List<Map<String, Object>> locationMapList,Integer retryCount,String IMEI){
        if(retryCount >= 100){
            return retryCount;
        }
        Boolean uploadFlag = Boolean.TRUE;
        while (prepareCall() && uploadFlag){
            int index = locationMapList.size() > 100 ? 100:locationMapList.size();
            List<Map<String, Object>> subList = locationMapList.subList(0,index);
            Boolean upload = uploadPoint(propertiesMap,subList,IMEI);
            if(!upload){
                log.error("上传经纬度列表失败，经纬度列表"+JsonUtils.toJsonString(subList));
            }
            locationMapList.removeAll(subList);
            if(CollectionUtils.isEmpty(locationMapList)){
                uploadFlag = Boolean.FALSE;
            }
        }
        if(CollectionUtils.isNotEmpty(locationMapList)){
            retryCount++;
            return upload(propertiesMap,locationMapList,retryCount,IMEI);
        }else{
            return retryCount;
        }
    }
    private Boolean uploadPoint(Map<String,Object> propertiesMap,List<Map<String, Object>> subLocationMapList,String IMEI){
        String goldenKey = MapUtils.getString(propertiesMap,"goldenKey");
        String serviceId = MapUtils.getString(propertiesMap,"serviceId");
        String terminalId = MapUtils.getString(propertiesMap,"terminalId");
        String traceId = MapUtils.getString(propertiesMap,"traceId");
        Map<String,Object> upMap = new HashMap<String,Object>();
        upMap.put("key", goldenKey);
        upMap.put("sid", serviceId);
        upMap.put("tid", terminalId);
        upMap.put("trid", traceId);
        JSONArray pointArray = new JSONArray();
        DecimalFormat df = new DecimalFormat("#.000000");
        for(Map<String, Object> locationMap:subLocationMapList){
            JSONObject point = new JSONObject();
            String lonLat = String.format("%s,%s",df.format(MapUtils.getDouble(locationMap,"locLon")),df.format(MapUtils.getDouble(locationMap,"locLat")));
            point.put("location",lonLat);
            point.put("locatetime",MapUtils.getLong(locationMap,"timestamp"));
            point.put("height",MapUtils.getDouble(locationMap,"altitude"));
            point.put("direction",MapUtils.getInteger(locationMap,"heading"));
            point.put("speed",MapUtils.getInteger(locationMap,"speed"));
            point.put("accuracy",MapUtils.getDouble(locationMap,"accuracy"));
            Map<String,Object> pointMap = new HashMap<>();
            if(StringUtils.isNotEmpty(IMEI)){
                pointMap.put(PROP_IMEI,IMEI);
            }
            if(StringUtils.isNotEmpty(MapUtils.getString(locationMap,"timestamp"))){
                pointMap.put(PROP_TIMESTAMP,MapUtils.getString(locationMap,"timestamp"));
            }
            if(MapUtils.isNotEmpty(pointMap)){
                point.put("props",pointMap);
            }
            pointArray.add(point);
        }
        upMap.put("points", pointArray);
        String uploadGpsResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "uploadGps"), upMap);
        JSONObject jsb =  JSONObject.fromObject(uploadGpsResult);
        String errorCode = null != jsb ? jsb.getString("errcode") : "";
        if(!"10000".equals(errorCode)) {
            //经纬度点上传失败
            log.error("上传经纬度点失败，异常："+errorCode);
            return false;
        }
        return true;
    }

    @Override
    public Map<String,Object> getWorkOrderDistance(WorkOrderT workOrderT) {
        return getWorkOrderTrace(workOrderT,1,20);
    }

    private Map<String,Object> getWorkOrderTrace(WorkOrderT workOrderT,Integer page,Integer pageSize){
        Map<String,Object> resultMap = new HashMap<>(2);

        Map<String,Object> properties = getGDProperties(workOrderT);
        Map<String,Object> getDistanceMap = new HashMap<String,Object>();
        getDistanceMap.put("key", MapUtils.getString(properties,"goldenKey"));
        getDistanceMap.put("sid", MapUtils.getString(properties,"serviceId"));
        getDistanceMap.put("tid", MapUtils.getString(properties,"terminalId"));
        getDistanceMap.put("trid", MapUtils.getString(properties,"traceId"));
        getDistanceMap.put("page",page);
        getDistanceMap.put("pagesize", pageSize);
        getDistanceMap.put("recoup", 1);
        getDistanceMap.put("gap", 3000);
        getDistanceMap.put("correction", "denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving");
        try {
            log.info("工单编号:" + workOrderT.getOrderNo() + ",的获取轨迹参数：" + JSON.toJSONString(getDistanceMap));
            String getDistanceResult = HttpClient.doPost(PropertiesUtil.getProperties("goldenUrl.properties", "getDistance"), getDistanceMap);
            log.info("工单编号:" + workOrderT.getOrderNo() + ",的获取轨迹返回：" + getDistanceResult);
            JSONObject jsb = JSONObject.fromObject(getDistanceResult);
            String errorCode = jsb.getString("errcode");
            if(!"10000".equals(errorCode)) {
                log.error("获取轨迹发生异常:"+jsb.toString());
                resultMap.put("result",Boolean.FALSE);
                return resultMap;
            }
            JSONObject data = (JSONObject) jsb.get("data");
            JSONObject trace = (JSONObject) data.getJSONArray("tracks").get(0);
            String distance = trace.getString("distance");
            Integer counts = trace.getInt("counts");
            JSONArray pointArray = trace.getJSONArray("points");
            List<Map<String,Object>> pointList = new ArrayList<>();
            if(null != pointArray && pointArray.size() >0){
               for (int i = 0;i<pointArray.size();i++){
                    Map<String,Object> pointMap = new HashMap<>();
                    JSONObject pointObj = (JSONObject) pointArray.get(i);
                    String[] lonLatArray = pointObj.getString("location").split(",");
                    pointMap.put("longitude",lonLatArray[0]);
                    pointMap.put("latitude",lonLatArray[1]);
                    if(pointObj.containsKey("props")){
                        JSONObject propObj = (JSONObject) pointObj.get("props");
                        if(propObj.containsKey("IMEI")){
                            pointMap.put("IMEI",propObj.getString("IMEI"));
                        }
                        if(propObj.containsKey("timestamp")){
                            pointMap.put("timestamp",propObj.getString("timestamp"));
                        }
                    }
                    /*if(pointObj.containsValue("locatetime")){
                        Long timestamp = pointObj.getLong("locatetime");
                        pointMap.put("timestamp",timestamp);
                    }*/
                    pointList.add(pointMap);
                };
            }
            resultMap.put("result",Boolean.TRUE);
            resultMap.put("distance",distance);
            resultMap.put("counts",counts);
            resultMap.put("points",pointList);
            log.error("result: "+resultMap);
        }catch (Exception e){
            resultMap.put("result",Boolean.FALSE);
            log.error(e.getMessage(),e);
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> getGDProperties(WorkOrderT workOrderT) {
        Map<String, Object> propertiesMap = new HashMap<>(4);
        // 获取高德Key
        String goldenKey = PropertiesUtil.getProperties("projectconfig.properties", "Golden.GoldenKey");
        propertiesMap.put("goldenKey",goldenKey);
        // 获取服务ID和终端ID
        String serviceId = null;
        String terminalId = null;
        String serviceTerminalKey = String.format("%d_%d", workOrderT.getOrderChannel(), workOrderT.getServiceStationId());
        String serviceTerminalId = MapUtils.getString(company_service, serviceTerminalKey, "");
        if (StringUtils.isEmpty(serviceTerminalId)) {
            Map<String, Object> map = getDataServiceTerminal(workOrderT, serviceTerminalKey);
            serviceId = MapUtils.getString(map, "serviceId");
            terminalId = MapUtils.getString(map, "terminalId");
        } else {
            String[] csStrArr = serviceTerminalId.split("_");
            if (csStrArr.length == 2) {
                serviceId = csStrArr[0];
                terminalId = csStrArr[1];
            } else {
                Map<String, Object> map = getDataServiceTerminal(workOrderT, serviceTerminalKey);
                serviceId = MapUtils.getString(map, "serviceId");
                terminalId = MapUtils.getString(map, "terminalId");
            }
        }
        propertiesMap.put("serviceId", serviceId);
        propertiesMap.put("terminalId", terminalId);

        //获取轨迹ID
        String traceId = null;
        String terminalTraceKey = String.format("%d_%d_%s", workOrderT.getServiceStationId(), workOrderT.getId(), workOrderT.getOrderNo());
        String terminalTrackId = MapUtils.getString(trace_service, terminalTraceKey, "");
        if (StringUtils.isEmpty(terminalTrackId)) {
            Map<String,Object> terminalTraceMap = getDataTerminalTrace(workOrderT,terminalTraceKey);
            traceId = MapUtils.getString(terminalTraceMap,"traceId");
        } else {
            String[] tsStrArr = terminalTrackId.split("_");
            if (tsStrArr.length == 2) {
                traceId = tsStrArr[1];
            } else {
                Map<String,Object> terminalTraceMap = getDataTerminalTrace(workOrderT,terminalTraceKey);
                traceId = MapUtils.getString(terminalTraceMap,"traceId");
            }
        }
        propertiesMap.put("traceId", traceId);
        return propertiesMap;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void downloadTrace(WorkOrderT workOrderT, UserT userT) {
        List<Map<String,Object>> allPointList = new ArrayList<>();
        Integer page = 1;
        Integer pageSize = 500;
        Map<String,Object> workOrderTraceMap = getWorkOrderTrace(workOrderT,page,pageSize);
        Boolean result = MapUtils.getBoolean(workOrderTraceMap,"result");
        if(result){
            Integer counts = MapUtils.getInteger(workOrderTraceMap,"counts");
            List<Map<String,Object>> pointList = (List)workOrderTraceMap.get("points");
            allPointList.addAll(pointList);
            Boolean hasMore = Boolean.TRUE;
            while (result && hasMore){
                if(counts.equals(pageSize)){
                    page++;
                    Map<String,Object> pageWorkOrderTraceMap =  getWorkOrderTrace(workOrderT,page,pageSize);
                    result = MapUtils.getBoolean(pageWorkOrderTraceMap,"result");
                    if(result){
                        allPointList.addAll((List)workOrderTraceMap.get("points"));
                        counts = MapUtils.getInteger(pageWorkOrderTraceMap,"counts");
                    }
                }else{
                    hasMore = Boolean.FALSE;
                }
            }
        }
        if(CollectionUtils.isNotEmpty(allPointList)){
            DecimalFormat df = new DecimalFormat("#.000000");
            for(Map<String,Object> locationMap:allPointList) {
                Map<String, Object> trackMap = new HashMap<String, Object>();
                trackMap.put("OrderId", workOrderT.getId());
                trackMap.put("LocLon", df.format(MapUtils.getDouble(locationMap,"longitude")));
                trackMap.put("LocLat", df.format(MapUtils.getDouble(locationMap,"latitude")));
                trackMap.put("Flag", 0);
                trackMap.put("Creator", userT.getId());
                trackMap.put("IMEI",MapUtils.getString(locationMap,"IMEI"));
                Long timestamp = MapUtils.getLong(locationMap,"timestamp");
                if(NumberUtils.isPositiveNum(timestamp)){
                    trackMap.put("CreateTime", Date_Util.GetTimeByTimesTamp(timestamp));
                }else {
                    trackMap.put("CreateTime", LocalTimeUtil.getRealCurrentTime());
                }
                techDealWithWorkOrderDao.saveOrderTrack(trackMap);
            }
        }
    }

    @Override
    public void getOrderTrackInfos(Map<String, Object> map) {
        HttpServletResponse response = (HttpServletResponse) map.get("response");
        Long orderId = MapUtils.getLong(map,"orderId");
        Map<String,Object> responseData = new HashMap<>(5);
        if(NumberUtils.isPositiveNum(orderId)){

            // 获取所有轨迹点
            List<Map<String,Object>> responseTrackList = new ArrayList<>();
            List<Map<String,Object>> dataTrackList = workOrderTrackTDao.getTrackList(orderId);
            if(CollectionUtils.isNotEmpty(dataTrackList)){
                for(Map<String,Object> dataTrack:dataTrackList){
                    Map<String,Object> responseTrack = new HashMap<>(3);
                    responseTrack.put("locLon",MapUtils.getString(dataTrack,"LocLon","0.0"));
                    responseTrack.put("locLat",MapUtils.getString(dataTrack,"LocLat","0.0"));
                    responseTrackList.add(responseTrack);
                }
            }
            responseData.put("trackList",responseTrackList);

            // 获取工单故障地点
            WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
            Map<String,Object> responseFaultInfo = new HashMap<>(2);
            responseFaultInfo.put("locLon",workOrderT.getLocLon());
            responseFaultInfo.put("locLat",workOrderT.getLocLat());
            responseData.put("faultInfo",responseFaultInfo);

            // 获取经销商地点
            Map<String,Object> responseStationInfo = new HashMap<>(2);
            Map<String,Object> stationMap = serviceStationDao.getServiceStationById(workOrderT.getServiceStationId());
            responseStationInfo.put("locLon",MapUtils.getFloatValue(stationMap,"PositionLon",0.0f));
            responseStationInfo.put("locLat",MapUtils.getFloatValue(stationMap,"PositionLat",0.0f));
            responseData.put("stationInfo",responseStationInfo);

            // 获取出发点地址

            Map<String,Object> departMap = workOrderFlowTDao.getWorkOrderFlowByOrderAndStatus(orderId, Dictionaries.OrderStatus_10.getIndex());
            if(MapUtils.isNotEmpty(departMap)){
                Map<String,Object> responseDepartInfo = new HashMap<>(2);
                responseDepartInfo.put("locLon",MapUtils.getFloatValue(departMap,"LocLon",0.0f));
                responseDepartInfo.put("locLat",MapUtils.getFloatValue(departMap,"LocLat",0.0f));
                responseData.put("departInfo",responseDepartInfo);
            }


            // 获取到达点地址
            Map<String,Object> responseArriveInfo = new HashMap<>(2);
            Map<String,Object> arriveMap = workOrderFlowTDao.getWorkOrderFlowByOrderAndStatus(orderId, Dictionaries.OrderStatus_11.getIndex());
            if(MapUtils.isNotEmpty(arriveMap)){
                responseArriveInfo.put("locLon",MapUtils.getFloatValue(arriveMap,"LocLon",0.0f));
                responseArriveInfo.put("locLat",MapUtils.getFloatValue(arriveMap,"LocLat",0.0f));
                responseData.put("arriveInfo",responseArriveInfo);
            }
        }
        ParameterTool.writeSuccessResponse(response,responseData);
    }

    private Map<String, Object> getDataServiceTerminal(WorkOrderT workOrderT, String serviceTerminalKey) {
        Map<String, Object> dataServiceTerminalMap = new HashMap<>(2);
        Map<String, Object> queryMap = new HashMap<>(2);
        queryMap.put("CompanyId", workOrderT.getOrderChannel());
        queryMap.put("ServiceStationId", workOrderT.getServiceStationId());
        Map<String, Object> serviceTerminalMap = techDealWithWorkOrderDao.getGolden_Company_Service(queryMap);
        if (MapUtils.isNotEmpty(serviceTerminalMap)) {
            String serviceId = MapUtils.getString(serviceTerminalMap, "gsid");
            String terminalId = MapUtils.getString(serviceTerminalMap, "gtid");
            dataServiceTerminalMap.put("serviceId", serviceId);
            dataServiceTerminalMap.put("terminalId", terminalId);
            company_service.put(serviceTerminalKey, String.format("%s_%s", serviceId, terminalId));
        }
        return dataServiceTerminalMap;
    }
    private Map<String, Object> getDataTerminalTrace(WorkOrderT workOrderT, String terminalTraceKey) {
        Map<String, Object> dataTerminalTraceMap = new HashMap<>(2);
        String traceId = null;
        Map<String, Object> queryMap = new HashMap<>(3);
        queryMap.put("CompanyId", workOrderT.getOrderChannel());
        queryMap.put("ServiceStationId", workOrderT.getServiceStationId());
        queryMap.put("OrderId", workOrderT.getId());
        Map<String, Object> tsMap = techDealWithWorkOrderDao.getTrace_Service(queryMap);
        if (MapUtils.isNotEmpty(tsMap)) {
            traceId = MapUtils.getString(tsMap, "gtrid");
            String terminalId = MapUtils.getString(tsMap, "gtrid");
            trace_service.put(terminalTraceKey,String.format("%s_%s",terminalId,traceId));
        }
        dataTerminalTraceMap.put("traceId",traceId);
        return dataTerminalTraceMap;
    }

    private Boolean prepareCall(){
        String time = LocalTimeUtil.getRealCurrentTime();
        long count = redisClientUtils.incr(RedisKeys.getGDCallCounts(time),1);
        if(count < 50){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

}
